home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / Making_a_32008097212006.psc / Engine_Lesson 8 adding frustum Culling and Collision detection / cQuest3D_Camera.cls next >
Text File  |  2006-07-20  |  23KB  |  853 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "cQuest3D_Camera"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. '==============================================================================================================
  15. '
  16. '       In this class module we define all variables needed for our Camera class
  17. '
  18. ' THIS MODULE CONTAINS VERY USEFUL AND HARD HAND CODED METHODS, IF YOU
  19. '   WANT TO USE THEM, GIVE CREDITS TO MY PERSON (Polaris),johna_pop@yahoo.fr
  20. '   I HAVE SPENT A LOT OF TIME ON THAT CAMERA CLASS, IT IS THE BEST I HAVE CODED
  21. '   AND THE BEST AVAILABLE IN VISUAL BASIC
  22. '
  23. '  USE IT, MODIFY IT BUT GIVE ME CREDIT
  24. '
  25. ' Polaris: http://perso.numericable.fr/~gazkole/malakoff/index.htm
  26. '
  27. '================================================================================================
  28.  
  29. Option Explicit
  30.  
  31. Private Type POINTAPI
  32.     x As Long
  33.     y As Long
  34. End Type
  35.  
  36. Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
  37. Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
  38.  
  39. Dim g_fAngleX  As Single '  0.0     'Rotation angle for the x-axis
  40. Dim g_fAngleY  As Single '  0.0     'Rotation angle for the y-axis
  41. Dim g_fAngleZ  As Single '  0.0     'Rotation angle for the y-axis
  42.  
  43. Dim g_fPosX    As Single '  0.0     'Camera position on the x-axis
  44. Dim g_fPosY    As Single '  1.2     'Camera position on the y-axis
  45. Dim g_fPosZ    As Single ' -8.0     'Camera position on the z-axis
  46.  
  47. 'for save datas
  48. Dim Save_fAngleX  As Single '  0.0     'Rotation angle for the x-axis
  49. Dim Save_fAngleY  As Single '  0.0     'Rotation angle for the y-axis
  50. Dim Save_fAngleZ  As Single '  0.0     'Rotation angle for the y-axis
  51.  
  52. Dim Save_fPosX    As Single '  0.0     'Camera position on the x-axis
  53. Dim Save_fPosY    As Single '  1.2     'Camera position on the y-axis
  54. Dim Save_fPosZ    As Single ' -8.0     'Camera position on the z-axis
  55.  
  56. Private RotMat As D3DMATRIX
  57. 'Private RotQuat As D3DQUATERNION
  58. '
  59. 'Private Save_RotMat As D3DMATRIX
  60. 'Private Save_RotQuat As D3DQUATERNION
  61.  
  62. Dim m_bMovedSinceLastUpdate As Boolean
  63.  
  64. Enum QUEST3D_PROJECTION_TYPE
  65.     PT_ORTHOGRAPHIC
  66.     PT_PERSPECTIVE_LH
  67.     'PT_PERSPECTIVE_RH
  68.  
  69. End Enum
  70.  
  71. Enum QUEST3D_CAMERA_STYLE
  72.     FREE_6DOF = 0
  73.     FPS_STYLE = 1
  74. End Enum
  75.  
  76. Dim CAM_TYPE As QUEST3D_CAMERA_STYLE
  77.  
  78. Dim m_ProjectionType As QUEST3D_PROJECTION_TYPE
  79.  
  80. Private M_vlastPOS As D3DVECTOR
  81. Private M_vDir As D3DVECTOR
  82. Private M_vVel As D3DVECTOR
  83.  
  84. Private Save_vlastPOS As D3DVECTOR
  85. Private Save_vDir As D3DVECTOR
  86. Private Save_vVel As D3DVECTOR
  87.  
  88. Private SAVEViewFrust As QUEST3D_FOV
  89.  
  90. Private Sub Class_Initialize()
  91.  
  92.     g_fAngleX = 0#       ' Rotation angle for the x-axis
  93.     g_fAngleY = 0#       ' Rotation angle for the y-axis
  94.     g_fAngleZ = 0#       ' Rotation angle for the y-axis
  95.  
  96.     g_fPosX = 0#         ' Camera position on the x-axis
  97.     g_fPosY = 1.2        ' Camera position on the y-axis
  98.     g_fPosZ = -8#        ' Camera position on the z-axis
  99.  
  100.     CAM_TYPE = FPS_STYLE
  101.  
  102.     m_ProjectionType = PT_PERSPECTIVE_LH
  103.  
  104.     Set_Position Vector(0, 0, 0)
  105.     Set_LookAt Vector(0, 0, 1)
  106.  
  107. End Sub
  108.  
  109. Function Get_Direction() As D3DVECTOR
  110.  
  111.     Get_Direction = M_vDir 'Vector(Data.matView.m13, Data.matView.m23, Data.matView.m33) '
  112.  
  113. End Function
  114.  
  115. Function Get_LastPosition() As D3DVECTOR
  116.  
  117.     Get_LastPosition = M_vlastPOS
  118.  
  119. End Function
  120.  
  121. Sub RecallLastPosition()
  122.  
  123.     g_fPosX = M_vlastPOS.x
  124.     g_fPosY = M_vlastPOS.y
  125.     g_fPosZ = M_vlastPOS.z
  126.  
  127.     m_bMovedSinceLastUpdate = True
  128.  
  129.     Update
  130.  
  131. End Sub
  132.  
  133. Function Get_MatrixProjection() As D3DMATRIX
  134.  
  135.     Get_MatrixProjection = Data.MatProjec
  136.  
  137. End Function
  138.  
  139. Function Get_MatrixView() As D3DMATRIX
  140.  
  141.     Get_MatrixView = Data.matView
  142.  
  143. End Function
  144.  
  145. Function Get_Position() As D3DVECTOR
  146.  
  147.     Get_Position = Vector(g_fPosX, g_fPosY, g_fPosZ)
  148.  
  149. End Function
  150.  
  151. Function Get_ScreenHeight() As Long
  152.  
  153.     Get_ScreenHeight = Data.Buffer_Height
  154.  
  155. End Function
  156.  
  157. Function Get_ScreenWidth() As Long
  158.  
  159.     Get_ScreenWidth = Data.Buffer_Width
  160.  
  161. End Function
  162.  
  163. Sub Get_RayPick(ByVal x As Single, ByVal y As Single, ByRef Vorg As D3DVECTOR, Vdir As D3DVECTOR)
  164.  
  165.   Dim dx, dy
  166.   Dim P1 As D3DVECTOR
  167.   Dim P2 As D3DVECTOR
  168.  
  169.   Dim invMatrix As D3DMATRIX, ViewMatrix As D3DMATRIX
  170.  
  171.     dx = Tan(Data.ViewFrust.FovAngle * 0.5) * (x / (Data.Buffer_Width * 0.5) - 1#) / Data.ViewFrust.Aspect
  172.  
  173.     dy = Tan(Data.ViewFrust.FovAngle * 0.5) * (1# - y / (Data.Buffer_Height * 0.5))
  174.  
  175.     Call obj_Device.GetTransform(D3DTS_VIEW, ViewMatrix)
  176.  
  177.     Call D3DXMatrixInverse(invMatrix, 0, ViewMatrix)
  178.  
  179.     P1 = Vector(dx * Data.ViewFrust.Near, dy * Data.ViewFrust.Near, Data.ViewFrust.Near)
  180.     P2 = Vector(dx * Data.ViewFrust.Far, dy * Data.ViewFrust.Far, Data.ViewFrust.Far)
  181.  
  182.     Call D3DXVec3TransformCoord(Vorg, P1, invMatrix)
  183.     Call D3DXVec3TransformCoord(Vdir, P2, invMatrix)
  184.  
  185. End Sub
  186.  
  187. Function Get_Rotation2() As D3DQUATERNION
  188.  
  189.   Dim Q As D3DQUATERNION
  190.  
  191.     D3DXQuaternionRotationMatrix Q, RotMat
  192.  
  193.     Get_Rotation2.x = Q.x
  194.     Get_Rotation2.y = Q.y
  195.     Get_Rotation2.z = Q.z
  196.     Get_Rotation2.w = Q.w
  197.  
  198. End Function
  199.  
  200. Function Get_RotationEuler() As D3DVECTOR
  201.  
  202.     Get_RotationEuler = Vector(g_fAngleX, g_fAngleY, g_fAngleZ)
  203.  
  204. End Function
  205.  
  206. Function Get_Velocity() As D3DVECTOR
  207.  
  208.   'Get_Velocity = M_vVel 'Vector(Data.matView.m13, Data.matView.m23, Data.matView.m33) '
  209.  
  210.     D3DXVec3Subtract Get_Velocity, Vector(g_fPosX, g_fPosY, g_fPosZ), Get_LastPosition
  211.  
  212. End Function
  213.  
  214. Function Get_VelocityNormalized() As D3DVECTOR
  215.  
  216.   Dim V As D3DVECTOR
  217.  
  218.     'Get_Velocity = M_vVel 'Vector(Data.matView.m13, Data.matView.m23, Data.matView.m33) '
  219.  
  220.     D3DXVec3Subtract V, Vector(g_fPosX, g_fPosY, g_fPosZ), Get_LastPosition
  221.     D3DXVec3Normalize Get_VelocityNormalized, V
  222.  
  223. End Function
  224.  
  225. Function Get_ViewDirection() As D3DVECTOR
  226.  
  227.     Get_ViewDirection = Vector(Data.matView.m13, Data.matView.m23, Data.matView.m33) '
  228.  
  229.     'D3DXVec3Normalize Get_ViewDirection, Get_ViewDirection
  230.  
  231. End Function
  232.  
  233. Public Sub Move_Backward(ByVal StepAmount As Single)
  234.  
  235.     If CAM_TYPE = FREE_6DOF Then
  236.  
  237.         g_fPosX = g_fPosX + Sin((g_fAngleY)) * Cos(g_fAngleX) * StepAmount
  238.         g_fPosY = g_fPosY - Sin(g_fAngleX) * StepAmount
  239.         g_fPosZ = g_fPosZ - Cos((g_fAngleY)) * Cos(g_fAngleX) * StepAmount
  240.       Else
  241.  
  242.         g_fPosX = g_fPosX + Sin((g_fAngleY)) * StepAmount
  243.         g_fPosZ = g_fPosZ - Cos((g_fAngleY)) * StepAmount
  244.     End If
  245.  
  246.     m_bMovedSinceLastUpdate = True
  247.  
  248. End Sub
  249.  
  250. Public Sub Move_Forward(ByVal StepAmount As Single)
  251.  
  252.     If CAM_TYPE = FREE_6DOF Then
  253.  
  254.         g_fPosX = g_fPosX - Sin((g_fAngleY)) * Cos(g_fAngleX) * StepAmount
  255.         g_fPosY = g_fPosY + Sin(g_fAngleX) * StepAmount
  256.         g_fPosZ = g_fPosZ + Cos((g_fAngleY)) * Cos(g_fAngleX) * StepAmount
  257.       Else
  258.  
  259.         g_fPosX = g_fPosX - Sin((g_fAngleY)) * StepAmount
  260.         g_fPosZ = g_fPosZ + Cos((g_fAngleY)) * StepAmount
  261.     End If
  262.  
  263.     m_bMovedSinceLastUpdate = True
  264.  
  265. End Sub
  266.  
  267. Sub Pop_CameraDatas()
  268.  
  269.     g_fAngleX = Save_fAngleX '= g_fAngleX 'Single '  0.0     'Rotation angle for the x-axis
  270.     g_fAngleY = Save_fAngleY '= g_fAngleY 'Single '  0.0     'Rotation angle for the y-axis
  271.     g_fAngleZ = Save_fAngleZ '= g_fAngleZ 'Single '  0.0     'Rotation angle for the y-axis
  272.  
  273.     g_fPosX = Save_fPosX '= g_fPosX 'Single '  0.0     'Camera position on the x-axis
  274.     g_fPosY = Save_fPosY '= g_fPosY 'Single '  1.2     'Camera position on the y-axis
  275.     g_fPosZ = Save_fPosZ '= g_fPosZ 'Single ' -8.0     'Camera position on the z-axis
  276.  
  277.     M_vlastPOS = Save_vlastPOS '= M_vlastPOS 'D3DVECTOR
  278.     M_vDir = Save_vDir '= M_vDir 'D3DVECTOR
  279.     M_vVel = Save_vVel '= M_vVel 'D3DVECTOR
  280.  
  281.     Data.ViewFrust = SAVEViewFrust
  282.  
  283.     m_bMovedSinceLastUpdate = 1
  284.  
  285.     Update
  286.  
  287. End Sub
  288.  
  289. Sub Push_CameraDatas()
  290.  
  291.     Save_fAngleX = g_fAngleX 'Single '  0.0     'Rotation angle for the x-axis
  292.     Save_fAngleY = g_fAngleY 'Single '  0.0     'Rotation angle for the y-axis
  293.     Save_fAngleZ = g_fAngleZ 'Single '  0.0     'Rotation angle for the y-axis
  294.  
  295.     Save_fPosX = g_fPosX 'Single '  0.0     'Camera position on the x-axis
  296.     Save_fPosY = g_fPosY 'Single '  1.2     'Camera position on the y-axis
  297.     Save_fPosZ = g_fPosZ 'Single ' -8.0     'Camera position on the z-axis
  298.  
  299.     Save_vlastPOS = M_vlastPOS 'D3DVECTOR
  300.     Save_vDir = M_vDir 'D3DVECTOR
  301.     Save_vVel = M_vVel 'D3DVECTOR
  302.  
  303.     SAVEViewFrust = Data.ViewFrust
  304.  
  305. End Sub
  306.  
  307. Public Sub Roll_Left(ByVal AngleAmount As Single)
  308.  
  309.     g_fAngleZ = g_fAngleZ + AngleAmount
  310.  
  311.     If (g_fAngleZ >= 360# * QUEST3D_RAD) Then
  312.  
  313.         g_fAngleZ = g_fAngleZ - 360# * QUEST3D_RAD
  314.     End If
  315.  
  316.     m_bMovedSinceLastUpdate = True
  317.  
  318. End Sub
  319.  
  320. Public Sub Roll_Right(ByVal AngleAmount As Single)
  321.  
  322.     g_fAngleZ = g_fAngleZ - AngleAmount
  323.  
  324.     If (g_fAngleZ < 0) Then
  325.  
  326.         g_fAngleZ = g_fAngleZ + 360# * QUEST3D_RAD
  327.     End If
  328.  
  329.     m_bMovedSinceLastUpdate = True
  330.  
  331. End Sub
  332.  
  333. Sub Rotate(vRotationRadian As D3DVECTOR)
  334.  
  335.     g_fAngleX = vRotationRadian.x
  336.     g_fAngleY = vRotationRadian.y
  337.     g_fAngleZ = vRotationRadian.z
  338.  
  339.     m_bMovedSinceLastUpdate = True
  340.  
  341. End Sub
  342.  
  343. Public Sub RotateByMouse(Optional ByVal MouseSpeed As Single = 0.001, Optional ByVal InvertMouse As Boolean = 0, Optional ByVal CenterMousePos As Boolean = 0)
  344.  
  345.     DIMouseDevice.GetDeviceStateMouse DIMOUSESTATE
  346.  
  347.     ' Turn left or right
  348.     If (DIMOUSESTATE.lX <> 0) Then
  349.  
  350.         g_fAngleY = g_fAngleY + (-DIMOUSESTATE.lX * MouseSpeed)
  351.  
  352.         If (g_fAngleY < 0#) Then
  353.  
  354.             g_fAngleY = 2 * QUEST3D_PI + g_fAngleY
  355.           ElseIf (g_fAngleY >= 2 * QUEST3D_PI) Then
  356.  
  357.             g_fAngleY = g_fAngleY - 2 * QUEST3D_PI
  358.         End If
  359.     End If
  360.  
  361.     ' Look up or down
  362.     If (DIMOUSESTATE.lY <> 0) Then
  363.  
  364.         If (InvertMouse) Then
  365.  
  366.             g_fAngleX = g_fAngleX + DIMOUSESTATE.lY * MouseSpeed
  367.  
  368.           Else
  369.  
  370.             g_fAngleX = g_fAngleX - DIMOUSESTATE.lY * MouseSpeed
  371.         End If
  372.  
  373.         If (g_fAngleX < 0#) Then
  374.  
  375.             g_fAngleX = 2 * QUEST3D_PI + g_fAngleX
  376.  
  377.           ElseIf (g_fAngleX >= 3 * QUEST3D_PI) Then
  378.  
  379.             g_fAngleX = g_fAngleX - 2 * QUEST3D_PI
  380.         End If
  381.  
  382.         If (g_fAngleX > QUEST3D_PI / 2# And g_fAngleX <= QUEST3D_PI) Then
  383.  
  384.             g_fAngleX = QUEST3D_PI / 2
  385.  
  386.           ElseIf (g_fAngleX > 180 * QUEST3D_RAD And g_fAngleX < 270# * QUEST3D_RAD) Then
  387.  
  388.             'g_fAngleX = 270# * QUEST3D_RAD
  389.         End If
  390.         
  391.     End If
  392.  
  393.     m_bMovedSinceLastUpdate = True
  394.  
  395.     If CenterMousePos Then SetCursorPos (Data.Buffer_Rect.Right - Data.Buffer_Rect.Left) / 2 + Data.Buffer_Rect.Left, (Data.Buffer_Rect.bottom - Data.Buffer_Rect.Top) / 2 + Data.Buffer_Rect.Top
  396.  
  397. End Sub
  398.  
  399. Sub RotateX(ByVal DegreeAngle As Single)
  400.  
  401.     g_fAngleX = QUEST3D_RAD * DegreeAngle
  402.     m_bMovedSinceLastUpdate = True
  403.  
  404. End Sub
  405.  
  406. Sub RotateY(ByVal DegreeAngle As Single)
  407.  
  408.     g_fAngleY = QUEST3D_RAD * DegreeAngle
  409.     m_bMovedSinceLastUpdate = True
  410.  
  411. End Sub
  412.  
  413. Sub RotateZ(ByVal DegreeAngle As Single)
  414.  
  415.     g_fAngleZ = QUEST3D_RAD * DegreeAngle
  416.     m_bMovedSinceLastUpdate = True
  417.  
  418. End Sub
  419.  
  420. Private Function ScreenTovec(ByVal Xp As Integer, ByVal Yp As Integer, ByVal m_fRadius As Single) As D3DVECTOR
  421.  
  422.   '// Scale to screen
  423.  
  424.   Dim x As Single, y As Single, sscale As Single, z As Single, mag As Single
  425.  
  426.     x = -(Xp - Data.Buffer_Width / 2) / (m_fRadius * Data.Buffer_Width / 2)
  427.     y = (Yp - Data.Buffer_Height / 2) / (m_fRadius * Data.Buffer_Height / 2)
  428.  
  429.     z = 0#
  430.     mag = x * x + y * y
  431.  
  432.     If (mag > 1#) Then
  433.  
  434.         sscale = 1# / Sqr(mag)
  435.         x = x + x * sscale
  436.         y = y + y * sscale
  437.  
  438.       Else
  439.         z = Sqr(1# - mag)
  440.     End If
  441.  
  442.     '// Return vector
  443.     ScreenTovec = Vector(x, y, z)
  444.  
  445. End Function
  446.  
  447. 'Private Function GetRotationFromCursor(fTrackBallRadius As Single) As D3DQUATERNION
  448. '
  449. 'Dim sx As Single, sy As Single, sscale As Single, sZ As Single, Mag As Single
  450. 'Dim PT As POINTAPI, d1 As Single, d2 As Single, t As Single
  451. 'Dim Quat As D3DQUATERNION
  452. 'Dim P1 As D3DVECTOR
  453. 'Dim P2 As D3DVECTOR, Vaxis As D3DVECTOR, vecDiff As D3DVECTOR
  454. 'Dim Fangle As Single
  455. '
  456. 'If Data.Buffer_Rect.Right = 0 Then Exit Function
  457. '
  458. 'Quat.w = 1
  459. '
  460. ''Data
  461. '
  462. '    Call GetCursorPos(PT)
  463. '    'GetClientRect( hWnd, rc )
  464. '    'Call ScreenToClient(Data.Hwindow, PT)
  465. '    sx = (((2# * PT.X) / (Data.Buffer_Rect.Right - Data.Buffer_Rect.Left)) - 1)
  466. '    sy = (((2# * PT.Y) / (Data.Buffer_Rect.Bottom - Data.Buffer_Rect.Top)) - 1)
  467. '
  468. '
  469. '    If (sx = 0# And sy = 0#) Then
  470. '      GetRotationFromCursor = Quat
  471. '      Exit Function
  472. '    End If
  473. '
  474. '    d2 = Sqr(sx * sx + sy * sy)
  475. '
  476. '    If (d2 < fTrackBallRadius * 0.707106781186548) Then _
  477.     '        sZ = Sqr(fTrackBallRadius * fTrackBallRadius - d2 * d2) _
  478.     '    Else _
  479.     '        sZ = (fTrackBallRadius * fTrackBallRadius) / (2# * d2)
  480. '
  481. '    ' Get two points on trackball's sphere
  482. '     P1 = Vector(sx, sy, sZ)
  483. '     P2 = Vector(0#, 0#, fTrackBallRadius)
  484. '
  485. '    ' Get axis of rotation, which is cross product of p1 and p2
  486. '
  487. '    Call D3DXVec3Cross(Vaxis, P1, P2)
  488. '
  489. '    ' Calculate angle for the rotation about that axis
  490. '     vecDiff.X = P2.X - P1.X
  491. '     vecDiff.Y = P2.Y - P1.Y
  492. '     vecDiff.Z = P2.Z - P1.Z
  493. '
  494. '
  495. '    t = D3DXVec3Length(vecDiff) / (2# * fTrackBallRadius)
  496. '    If (t > 1#) Then t = 1#
  497. '    If (t < -1#) Then t = -1#
  498. '    Fangle = 2# * farcSin(t)
  499. '
  500. '    ' Convert axis to quaternion
  501. '    Quat.w = 0
  502. '
  503. '    Call D3DXQuaternionRotationAxis(Quat, Vaxis, Fangle)
  504. '    GetRotationFromCursor = Quat
  505. '
  506. 'End Function
  507. '
  508.  
  509. Sub Set_camera(vPos As D3DVECTOR, LookAt As D3DVECTOR)
  510.  
  511.     If VECTOR_Compare(vPos, Vector(g_fPosX, g_fPosY, g_fPosZ), 0.005) Then Exit Sub
  512.  
  513.     g_fPosX = vPos.x
  514.     g_fPosY = vPos.y
  515.     g_fPosZ = vPos.z
  516.  
  517.     Set_LookAt LookAt
  518.  
  519. End Sub
  520.  
  521. Sub Set_CameraProjectionType(ProjType As QUEST3D_PROJECTION_TYPE)
  522.  
  523.     m_ProjectionType = ProjType
  524.     UpdateFrustum
  525.  
  526. End Sub
  527.  
  528. Function Get_CameraProjectionType() As QUEST3D_PROJECTION_TYPE
  529.  
  530.     Get_CameraProjectionType = m_ProjectionType
  531.  
  532. End Function
  533.  
  534. Sub Set_CameraStyle(Style As QUEST3D_CAMERA_STYLE)
  535.  
  536.     CAM_TYPE = Style
  537.  
  538. End Sub
  539.  
  540. Function Get_CameraStyle() As QUEST3D_CAMERA_STYLE
  541.  
  542.     Get_CameraStyle = CAM_TYPE
  543.  
  544. End Function
  545.  
  546. Sub Set_Direction(Vdir As D3DVECTOR)
  547.  
  548.   Dim Vat As D3DVECTOR
  549.   Dim Vlook As D3DVECTOR
  550.   Dim VANG As D3DVECTOR
  551.  
  552.     Vlook = Get_Position
  553.     Vat = Vector(Vlook.x + Vdir.x * 10, Vlook.y + Vdir.y * 10, Vlook.z + Vdir.z * 10)
  554.  
  555.     GetRotationFromTO Vlook, Vat, VANG
  556.  
  557.     g_fAngleX = VANG.x
  558.     g_fAngleY = VANG.y
  559.     g_fAngleZ = VANG.z
  560.  
  561.     m_bMovedSinceLastUpdate = True
  562.  
  563. End Sub
  564.  
  565. Sub Set_LookAt(Vlook As D3DVECTOR)
  566.  
  567.     m_bMovedSinceLastUpdate = True
  568.  
  569.     '  Dim VANG As D3DVECTOR
  570.     '  Dim fXRot As Single, fYRot As Single, fXDiff As Single, fYDiff As Single, fZDiff As Single
  571.   Dim currentVelocity As D3DVECTOR
  572.     '      fXDiff = Vlook.x - g_fPosX
  573.     '      fYDiff = Vlook.y - g_fPosY
  574.     '      fZDiff = Vlook.z - g_fPosZ
  575.     '
  576.     '      fXDiff = g_fPosX - Vlook.x
  577.     '      fYDiff = g_fPosY - Vlook.y
  578.     '      fZDiff = g_fPosZ - Vlook.z
  579.  
  580.     'D3DXVec3Subtract currentVelocity, Vlook, Vector(g_fPosX, g_fPosY, g_fPosZ)
  581.  
  582.     currentVelocity.x = Vlook.x - g_fPosX
  583.     currentVelocity.y = Vlook.y - g_fPosY
  584.     currentVelocity.z = Vlook.z - g_fPosZ
  585.  
  586.     D3DXVec3Normalize currentVelocity, currentVelocity
  587.     '    '
  588.     '    '    'GetRotationFromTO Vector(g_fPosX, g_fPosY, g_fPosZ), Vlook, VANG
  589.     '    '
  590.     '        g_fAngleY = Arctan(-fYDiff, sqr(fXDiff * fXDiff + fZDiff * fZDiff))
  591.     '        g_fAngleX = Arctan(fXDiff, fZDiff)
  592.     '
  593.     '        'g_fAngleX = VANG.x
  594.     ''    g_fAngleY = VANG.y
  595.     ''    g_fAngleZ = VANG.z
  596.  
  597.     '
  598.     '        If (currentVelocity.x <> 0#) Then
  599.     '
  600.     '            g_fAngleY = -atn(currentVelocity.z / currentVelocity.x)
  601.     '
  602.     ''        ElseIf (currentVelocity.x < 0#) Then
  603.     ''
  604.     ''                 g_fAngleY = -atn(currentVelocity.z / currentVelocity.x)
  605.     ''
  606.     ''        ElseIf (currentVelocity.x = 0#) Then
  607.     ''
  608.     ''                g_fAngleY = 0
  609.     '        End If
  610.     '
  611.     '
  612.     '     If currentVelocity.x <> 0 Or currentVelocity.z <> 0 Then
  613.     '        g_fAngleY = atn(currentVelocity.y / _
  614.         '                sqr(currentVelocity.z * currentVelocity.z _
  615.         '                + currentVelocity.x * currentVelocity.x))
  616.     '    End If
  617.  
  618.     If currentVelocity.z <> 0 Or currentVelocity.x <> 0 Then
  619.         g_fAngleX = Atn(currentVelocity.y / _
  620.                     Sqr(currentVelocity.z * currentVelocity.z _
  621.                     + currentVelocity.x * currentVelocity.x))
  622.     End If
  623.  
  624.     If currentVelocity.z <> 0 Then
  625.         g_fAngleY = -ArcTan(currentVelocity.x, currentVelocity.z)
  626.     End If
  627.  
  628. End Sub
  629.  
  630. Sub Set_Position(vPos As D3DVECTOR)
  631.  
  632.     If VECTOR_Compare(vPos, Vector(g_fPosX, g_fPosY, g_fPosZ), 0.005) Then Exit Sub
  633.  
  634.     g_fPosX = vPos.x
  635.     g_fPosY = vPos.y
  636.     g_fPosZ = vPos.z
  637.  
  638.     m_bMovedSinceLastUpdate = True
  639.  
  640. End Sub
  641.  
  642. Sub Set_Position2(x As Single, y As Single, z As Single)
  643.  
  644.     If VECTOR_Compare(Vector(x, y, z), Vector(g_fPosX, g_fPosY, g_fPosZ), 0.005) Then Exit Sub
  645.  
  646.     g_fPosX = x
  647.     g_fPosY = y
  648.     g_fPosZ = z
  649.  
  650.     m_bMovedSinceLastUpdate = True
  651.  
  652. End Sub
  653.  
  654. Sub Set_ViewFrustum(ByVal Near As Single, ByVal Far As Single, ByVal FovAngle As Single, Optional ByVal Aspect As Single = -1)
  655.  
  656.     If Aspect = -1 Then Aspect = Data.Buffer_Width / Data.Buffer_Height
  657.     With Data.ViewFrust
  658.         .Aspect = Aspect
  659.         .Near = Near
  660.         .Far = Far
  661.         .FovAngle = FovAngle
  662.  
  663.     End With
  664.  
  665.     Data.FRUSTUM_HASCHANGED = True
  666.     'UpdateFrustum
  667.  
  668. End Sub
  669.  
  670. Function Get_FovAngle() As Single
  671.  
  672.     Get_FovAngle = Data.ViewFrust.FovAngle
  673.  
  674. End Function
  675.  
  676. Public Sub Strafe_Down(ByVal StepAmount As Single)
  677.  
  678.     g_fPosY = g_fPosY - StepAmount
  679.  
  680.     m_bMovedSinceLastUpdate = True
  681.  
  682. End Sub
  683.  
  684. Public Sub Strafe_Left(ByVal StepAmount As Single)
  685.  
  686.     g_fPosX = g_fPosX - Sin((g_fAngleY + 90 * QUEST3D_RAD#)) * StepAmount
  687.     g_fPosZ = g_fPosZ + Cos((g_fAngleY + 90 * QUEST3D_RAD)) * StepAmount
  688.  
  689.     m_bMovedSinceLastUpdate = True
  690.  
  691. End Sub
  692.  
  693. Public Sub Strafe_Right(ByVal StepAmount As Single)
  694.  
  695.     g_fPosX = g_fPosX - Sin((g_fAngleY - 90 * QUEST3D_RAD)) * StepAmount
  696.     g_fPosZ = g_fPosZ + Cos((g_fAngleY - 90 * QUEST3D_RAD)) * StepAmount
  697.  
  698.     m_bMovedSinceLastUpdate = True
  699.  
  700. End Sub
  701.  
  702. Public Sub Strafe_Up(ByVal StepAmount As Single)
  703.  
  704.     g_fPosY = g_fPosY + StepAmount
  705.  
  706.     m_bMovedSinceLastUpdate = True
  707.  
  708. End Sub
  709.  
  710. Public Sub Turn_Down(ByVal AngleAmount As Single)
  711.  
  712.     g_fAngleX = g_fAngleX - AngleAmount
  713.  
  714.     If (g_fAngleX < 0) Then
  715.  
  716.         g_fAngleX = g_fAngleX + 360# * QUEST3D_RAD
  717.     End If
  718.  
  719.     m_bMovedSinceLastUpdate = True
  720.  
  721. End Sub
  722.  
  723. Public Sub Turn_Left(ByVal AngleAmount As Single)
  724.  
  725.     g_fAngleY = g_fAngleY + AngleAmount
  726.  
  727.     If (g_fAngleY >= 360# * QUEST3D_RAD) Then
  728.  
  729.         g_fAngleY = g_fAngleY - 360# * QUEST3D_RAD
  730.     End If
  731.  
  732.     m_bMovedSinceLastUpdate = True
  733.  
  734. End Sub
  735.  
  736. Public Sub Turn_Right(ByVal AngleAmount As Single)
  737.  
  738.     g_fAngleY = g_fAngleY - AngleAmount
  739.  
  740.     If (g_fAngleY < 0) Then
  741.  
  742.         g_fAngleY = g_fAngleY + 360# * QUEST3D_RAD
  743.     End If
  744.  
  745.     m_bMovedSinceLastUpdate = True
  746.  
  747. End Sub
  748.  
  749. Public Sub Turn_Up(ByVal AngleAmount As Single)
  750.  
  751.     g_fAngleX = g_fAngleX + AngleAmount
  752.  
  753.     If (g_fAngleX >= 360# * QUEST3D_RAD) Then
  754.  
  755.         g_fAngleX = g_fAngleX - 360# * QUEST3D_RAD
  756.     End If
  757.  
  758.     m_bMovedSinceLastUpdate = True
  759.  
  760. End Sub
  761.  
  762. Sub Update(Optional ByVal UpdateViewFrustum As Boolean = True)
  763.  
  764.     If Not m_bMovedSinceLastUpdate Then Exit Sub
  765.  
  766.   Dim vecEyePoint As D3DVECTOR     'The eye point
  767.   Dim vecLookatPoint As D3DVECTOR  'The camera look-at target
  768.   Dim vecUp As D3DVECTOR           'The current world's up
  769.   Dim matRotationX As D3DMATRIX     'The matrix that rotates around the x-axis
  770.   Dim matRotationY As D3DMATRIX     'The matrix that rotates around the y-axis
  771.   Dim matRotationZ As D3DMATRIX     'The matrix that rotates around the y-axis
  772.  
  773.     'Dim matRotation As D3DMATRIX      'The matrix that rotates around the x and y-axis
  774.   Dim matWorld As D3DMATRIX         'The world transformation matrix
  775.   Dim matView As D3DMATRIX          'The view transformation matrix
  776.  
  777.     If Not VECTOR_Compare(M_vlastPOS, Vector(g_fPosX, g_fPosY, g_fPosZ), QUEST3D_EPSILON) Then
  778.  
  779.         M_vlastPOS = Data.EYES.EYE 'Vector(g_fPosX, g_fPosY, g_fPosZ)
  780.         M_vDir = Vector(g_fPosX - M_vlastPOS.x, g_fPosY - M_vlastPOS.y, g_fPosZ - M_vlastPOS.z)
  781.  
  782.         Data.EYES.Dir = M_vDir
  783.         M_vVel = M_vDir
  784.  
  785.         D3DXVec3Normalize M_vDir, M_vDir
  786.  
  787.         M_vVel = M_vDir
  788.         'D3DXVec3Normalize M_vDir, M_vDir
  789.         Data.EYES.DirNormalized = M_vDir
  790.     End If
  791.  
  792.     vecEyePoint = Vector(g_fPosX, g_fPosY, g_fPosZ)
  793.     vecLookatPoint = Vector(g_fPosX, g_fPosY, g_fPosZ + 0.001)
  794.     vecUp = Vector(0#, 1#, 0#)
  795.  
  796.     'update datas
  797.     Data.EYES.EYE = vecEyePoint
  798.     Data.EYES.Dest_at = vecLookatPoint
  799.  
  800.     Call D3DXMatrixLookAtLH(matView, vecEyePoint, vecLookatPoint, vecUp)
  801.  
  802.     '    D3DXMatrixIdentity matView
  803.     '    D3DXMatrixTranslation matView, g_fPosX, g_fPosY, g_fPosZ
  804.     '
  805.  
  806.     Call D3DXMatrixRotationX(matRotationX, (g_fAngleX))
  807.     Call D3DXMatrixRotationY(matRotationY, (g_fAngleY))
  808.     Call D3DXMatrixRotationZ(matRotationZ, (g_fAngleZ))
  809.  
  810.     Data.EYES.AngX = g_fAngleX
  811.     Data.EYES.ANGy = g_fAngleY
  812.     Data.EYES.ANGz = g_fAngleZ
  813.  
  814.     Call D3DXMatrixMultiply(RotMat, matRotationY, matRotationX)
  815.     Call D3DXMatrixMultiply(RotMat, RotMat, matRotationZ)
  816.  
  817.     Call D3DXMatrixMultiply(matView, matView, RotMat)
  818.  
  819.     Call obj_Device.SetTransform(D3DTS_VIEW, matView)
  820.     Data.matView = matView
  821.  
  822.     m_bMovedSinceLastUpdate = False
  823.  
  824.     If Data.FRUSTUM_HASCHANGED Then UpdateFrustum
  825.  
  826.     If UpdateViewFrustum Then _
  827.        SetUpFrustum
  828.  
  829. End Sub
  830.  
  831. Private Sub UpdateFrustum()
  832.  
  833.     If m_ProjectionType = PT_PERSPECTIVE_LH Then
  834.         D3DXMatrixPerspectiveFovLH Data.MatProjec, Data.ViewFrust.FovAngle, Data.ViewFrust.Aspect, Data.ViewFrust.Near, Data.ViewFrust.Far
  835.  
  836.         'ElseIf m_ProjectionType = PT_PERSPECTIVE_RH Then
  837.         ' D3DXMatrixPerspectiveFovRH Data.MatProjec, Data.ViewFrust.FovAngle, Data.ViewFrust.Aspect, Data.ViewFrust.Near, Data.ViewFrust.Far
  838.  
  839.       Else
  840.         Call D3DXMatrixOrthoLH(Data.MatProjec, Data.Buffer_Width, Data.Buffer_Height, 0#, Data.ViewFrust.Far)
  841.         'Call D3DXMatrixOrthoLH(Data.MatProjec, 0#, Data.Buffer_Width, 0#, Data.Buffer_Height, 0#, 1#)
  842.  
  843.     End If
  844.  
  845.     'm_matProj = Data.MatProjec
  846.  
  847.     obj_Device.SetTransform D3DTS_PROJECTION, Data.MatProjec
  848.  
  849.     SetUpFrustum
  850.     Data.FRUSTUM_HASCHANGED = 0
  851.  
  852. End Sub
  853.